package com.zxmr.domain.service;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.zxmr.CommonInit;
import com.zxmr.db.DBManager;
import com.zxmr.domain.account.Role;
import com.zxmr.domain.account.RoleForUser;
import com.zxmr.domain.account.User;
import com.zxmr.domain.component.PageForUser;

public class UserService {
	
	DBManager db = CommonInit.getDBManager();
	/**
	 * insert
	 * @param user
	 * @return
	 */
	public boolean addUser(User user)
	{
		try {
			db.getMapper().insert("user.add", user);
			return true;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}
	/**
	 * update
	 * @param user
	 * @return
	 */
	public boolean updateUser(User user)
	{
		try {
			db.getMapper().update("user.update", user);
			return true;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}
	/**
	 * query by name
	 * @param name
	 * @return
	 */
	public User findUser(String name)
	{
		try{
			return (User)db.getMapper().queryForObject("user.findByName", name);
		}catch(SQLException e){
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * query by id
	 * @param name
	 * @return
	 */
	public User findUser(int id)
	{
		try{
			return (User)db.getMapper().queryForObject("user.findByID", id);
		}catch(SQLException e){
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * query by email
	 * @param email
	 * @return
	 */
	public User findByEmail(String email)
	{
		try{
			return (User)db.getMapper().queryForObject("user.findByEmail", email);
		}catch(SQLException e){
			e.printStackTrace();
		}
		return null;
	}
	
	public String getUserName(int id)
	{
		try{
			return (String)db.getMapper().queryForObject("user.getName", id);
		}catch(SQLException e){
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * find all user based on company
	 * @param company
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<User> findAllUserByCompany(int company)
	{
		try{
			return (List<User>)db.getMapper().queryForList("user.findByCompany", company);
		}catch(SQLException e){
			e.printStackTrace();
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public List<User> findAllSimpleUserByCompany(int company)
	{
		try{
			return (List<User>)db.getMapper().queryForList("user.findByCompanySimple", company);
		}catch(SQLException e){
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * update role for user
	 * @param user
	 * @param roles
	 */
	public boolean setRolesForUser(User user,List<Role> roles)
	{
		
		try
		{
			List<RoleForUser> rfes = getAllRoleForUser(user);
			List<Integer> needAddRole = getNeedAddRolesForUser(roles,rfes);
			List<Integer> needDeleteRole = getNeedDeleteRolesForUser(roles,rfes);
			
			db.getMapper().startTransaction();
			addRolesForUser(needAddRole,user);
			deleteRolesForUser(needDeleteRole,user);
			db.getMapper().commitTransaction();
			return true;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}finally{
			try {
				db.getMapper().endTransaction();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		return false;
	}
	/**
	 * query all role for user
	 * @param user
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Role> getAllRole(User user)
	{
		try{
			return (List<Role>)db.getMapper().queryForList("user.queryAllRole", user.getId());
		}catch(SQLException e){
			e.printStackTrace();
		}
		return null;
	}
	@SuppressWarnings("unchecked")
	private List<RoleForUser> getAllRoleForUser(User user) throws SQLException
	{
		return (List<RoleForUser>)db.getMapper().queryForList("user.queryAllRoleForUser", user.getId());
	}
	private void addRolesForUser(List<Integer> roles,User user) throws SQLException
	{
		for(int i : roles)
		{
			RoleForUser rfe = new RoleForUser();
			rfe.setUser(user.getId());
			rfe.setRole(i);
			db.getMapper().insert("user.addRole", rfe);
		}
	}
	private void deleteRolesForUser(List<Integer> roles,User user) throws SQLException
	{
		if(roles == null || roles.isEmpty())return;
		for(int i : roles)
		{
			RoleForUser rfe = new RoleForUser();
			rfe.setUser(user.getId());
			rfe.setRole(i);
			db.getMapper().delete("user.deleteRole", rfe);
		}
	}
	private List<Integer> getNeedAddRolesForUser(List<Role> newRoles,List<RoleForUser> oldRoles)
	{
		List<Integer> needAddRole = new ArrayList<Integer>();
		if(newRoles == null)return needAddRole;
		
		for(Role role : newRoles)
		{
			boolean found = false;
			for(RoleForUser rfe : oldRoles)
			{
				if(rfe.getRole() == role.getId())
				{
					found = true;
					break;
				}
			}
			if(!found)
			{
				needAddRole.add(role.getId());
			}
		}
		return needAddRole;
	}
	
	private List<Integer> getNeedDeleteRolesForUser(List<Role> newRoles,List<RoleForUser> oldRoles)
	{
		List<Integer> needDeleteRole = new ArrayList<Integer>();
		if(oldRoles == null)return needDeleteRole;
		
		for(RoleForUser rfe : oldRoles)
		{
			boolean found = false;
			for(Role role : newRoles)
			{
				if(rfe.getRole() == role.getId())
				{
					found = true;
					break;
				}
			}
			if(!found)
			{
				needDeleteRole.add(rfe.getRole());
			}
		}
		return needDeleteRole;
	}
	@SuppressWarnings("unchecked")
	public List<PageForUser> getAllPageForUser(int user)
	{
		try
		{
			return (List<PageForUser>)db.getMapper().queryForList("page.findAllPage", user);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	
	public boolean addPageForUser(PageForUser page)
	{
		try
		{
			db.getMapper().insert("page.addPageForUser", page);
			
			return true;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return false;
	}
	public boolean deletePageForUser(PageForUser page)
	{
		try
		{
			db.getMapper().delete("page.deletePageForUser", page);
			
			return true;
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return false;
	}
}
